<?php
/**
 * Framework_Module_User_OpenIDConsumer
 *
 * @author      Ian Szewczyk <roamzero@gmail.com>
 * @copyright   (c) 2007 Ian Szewczyk. All rights reserved.
 * @license     http://www.opensource.org/licenses/bsd-license.php
 * @package Module
 * @filesource
 */


/**
 * Framework_Module_User_OpenIDConsumer
 *
 * @author Ian Szewczyk <roamzero@gmail.com>
 * @package Module
 */
class Framework_Module_User_OpenIDConsumer extends Framework_Module_User {

	/**
	 * __construct
	 *
	 * Initializes the module: sets the default presenter, the allowed
	 * conrollers, and the allowed events
	 *
	 * @access 		public
	 * @return 		void
	 */
	public function __construct()
	{
		parent::__construct();
		$this->presenter = 'None';

	}

	/**
     * __default
     *
     * Process openID form
     *
     * @access 		public
     * @return 		mixed 		boolean true on success, PEAR_Error on failure
     */
	public function __default()
	{


		if ($this->session->OpenIDConsumerStart == true) {

			return $this->processFinish();

		}

		$this->forms['form'] = Framework_Quickform::factory('openIDLogin', 'post', Framework::$request->getHTTPPath(), null, null, true);
		$this->forms['form']->addElement('text','identity','Identity: ', 'size="30" class="textInput" id="identity"');
		$this->forms['form']->addElement('submit','btnSubmit','Remote Login','class="button" id="btnSubmit"');
		$this->forms['form']->addElement('hidden','from');
		// Filter
		$this->forms['form']->applyFilter('__ALL__', 'trim');
		// Rules
		$this->forms['form']->addRule('identity', 'Identity is required', 'required');
		//$this->forms['form']->addRule('identity','Identity must be URL','regex','/^http:\/\/[-a-z0-9]+(\.[-a-z0-9]+)*\.[a-z]{1,3}\/.*$/i');
		// Process OID form
		if ($this->forms['form']->validate()) {
			$result = $this->forms['form']->process(array($this, 'process'));
		} else {
			if ($this->forms['form']->isSubmitted() && $this->forms['form']->getSubmitValue('from')) {
				Framework_Header::redirect($this->forms['form']->getSubmitValue('from'));
			} else {
				Framework_Header::redirect(Framework::$request->getBaseHTTPPath());
			}

		}

	}

	/**
     * process
     *
     *
     * @access 		public
     * @param 		array		$data		Data to process
     * @return 		mixed 		boolean true on success, PEAR_Error on failure
     */
	public function process($data)
	{

		if (!$data['from']) {
			Framework_Header::redirect(Framework::$request->getBaseHTTPPath());
		} else {
			$this->session->OpenIDFrom = $data['from'];
		}

		$consumer = Framework_OpenID::factoryConsumer();
		if (PEAR::isError($consumer)) {
			$this->session->destroy();
			return $consumer;
		}
		
		if (preg_match("/^([a-zA-Z0-9])+([a-zA-Z0-9._-])*@([a-zA-Z0-9_-])+([a-zA-Z0-9._-]+)+$/", $data['identity'])) {
			$peopletabLogin = explode('@', $data['identity']);
			$identity = 'http://'.$peopletabLogin[0].'/'.$peopletabLogin[1];	
		} else {
			$identity = $data['identity'];
		}
		$request = $consumer->start($identity);

		if (!PEAR::isError($request)) {
			$this->session->OpenIDConsumerStart = true;
			if ($request->shouldSendRedirect()) {
				$redirect_url = $request->redirectURL(Framework::$request->getBaseHTTPPath(), Framework::$request->getHTTPPath());

				// If the redirect URL can't be built, display an error
				// message.
				if (Auth_OpenID::isFailure($redirect_url)) {
					return PEAR::raiseError("Could not redirect to server: " . $redirect_url->message);
				} else {
					// Send redirect.
					header("Location: ".$redirect_url);
					exit(0);
				}
			} else {
				// Generate form markup and render it.
				$form_id = 'openid_message';
				$form_html = $request->formMarkup(Framework::$request->getBaseHTTPPath(), Framework::$request->getHTTPPath(), false, array('id' => $form_id));

				// Display an error if the form markup couldn't be generated;
				// otherwise, render the HTML.
				if (Auth_OpenID::isFailure($form_html)) {
					return PEAR::raiseError("Could not redirect to server: " . $form_html->message);
				} else {
					$page_contents = array(
					"<html><head><title>",
					"OpenID transaction in progress",
					"</title></head>",
					"<body onload='document.getElementById(\"".$form_id."\").submit()'>",
					$form_html,
					"</body></html>");

					print implode("\n", $page_contents);
					exit(0);
				}
					
					
			}
		} else {
			$this->session->destroy();
		}
	}

	/**
     * processFinish
     *
     *
     * @access 		public
     * @return 		mixed 		void, PEAR_Error on failure
     */
	public function processFinish()
	{

		$this->session->OpenIDConsumerStart = false;
		$consumer = Framework_OpenID::factoryConsumer();
		$response = $consumer->finish();

		if ($response->status == Auth_OpenID_CANCEL) {
			// This means the authentication was cancelled.
			Framework_Header::redirect($this->session->OpenIDFrom);
		} else if ($response->status == Auth_OpenID_FAILURE) {
			$msg = "OpenID authentication failed: " . $response->message;
			return PEAR::raiseError($msg);
		} else if ($response->status == Auth_OpenID_SUCCESS) {

		
			$peopletab = $response->extensionResponse('http://peopletab.com/-/protocol/0', false);
			
			if (is_array($peopletab)) {
					
				$siteUserTable = Framework_DB::tableFactory('SiteUser');
					
				$filter = array('siteDomain'=>$peopletab['siteDomain'],'userName'=>$peopletab['userName']);
					
				$siteUserTable->load($filter);
					
				if($siteUserTable->isLoaded) {
					$idSiteUser = $siteUserTable->idSiteUser;
				} else {
					$idSiteUser = $siteUserTable->nextID();
				}
					
				foreach ($peopletab as $k => $v) {
					$siteUserTable->$k = $v;
				}
					
				$result = $siteUserTable->save();
					
				if (!PEAR::isError($result)) {
					$this->sessionLogin($idSiteUser);
					Framework_Header::redirect($this->session->OpenIDFrom);
				} else {
					
					return $result;
				}
					
					
			}

		}
	}



	/**
     * __destruct
     *
     *
     * @access 		public
     * @return 		void
     */
	public function __destruct()
	{
		parent::__destruct();
	}
}

?>